<script setup lang="ts">
import { computed, reactive, ref, useAttrs, watch } from 'vue';
import type { Shortcuts } from 'naive-ui/es/date-picker/src/interface';
import type { DatePickerType } from 'naive-ui/es/date-picker/src/config';
import { $t } from '@/locales';

interface Props {
  modelValue?: string;
  // 日期范围是否显示00:00:00 23:59:59时分秒
  plusTime?: Boolean;
  // 快捷配置
  shortcuts?: Shortcuts;
  // 是否开启快捷方式
  isPickerOptions?: Boolean;
  // 时间类型
  /** week周；month月；year年；dates多个日期；months多个月；years多个年；daterange日期范围；monthrange月份范围 datetime日期和时间点;datetimerange日期和时间点范围 */
  type: DatePickerType;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'update:modelValue'): void;
  (e: 'change'): void;
}

const emit = defineEmits<Emits>();

const attrs = useAttrs();

// vue3 v-model简写
const time: any = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-expect-error
    emit('update:modelValue', val);
  }
});

const DatePicker = ref();

interface TypeAttrs {
  [key: string]: object;
}
const attrsBind = computed(() => {
  const baseAttrs: TypeAttrs = {
    date: { 'value-format': 'yyyy-MM-dd', placeholder: `${$t('common.component.dataRangePicker.placeholder.date')}` },
    dates: { 'value-format': 'yyyy-MM-dd', placeholder: `${$t('common.component.dataRangePicker.placeholder.date')}` },
    week: { format: 'yyyy 第 ww 周', placeholder: `${$t('common.component.dataRangePicker.placeholder.week')}` },
    month: {
      'value-format': 'yyyy-MM',
      format: 'yyyy-MM',
      placeholder: `${$t('common.component.dataRangePicker.placeholder.month')}`
    },
    months: {
      'value-format': 'yyyy-MM',
      format: 'yyyy-MM',
      placeholder: `${$t('common.component.dataRangePicker.placeholder.month')}`
    },
    year: {
      'value-format': 'yyyy',
      format: 'yyyy',
      placeholder: `${$t('common.component.dataRangePicker.placeholder.year')}`
    },
    years: {
      'value-format': 'yyyy',
      format: 'yyyy',
      placeholder: `${$t('common.component.dataRangePicker.placeholder.year')}`
    },
    daterange: {
      'value-format': 'yyyy-MM-dd',
      'range-separator': '~',
      'start-placeholder': `${$t('common.component.dataRangePicker.placeholder.daterangeStart')}`,
      'end-placeholder': `${$t('common.component.dataRangePicker.placeholder.daterangeEnd')}`
    },
    monthrange: {
      'value-format': 'YYYY-MM',
      'range-separator': '~',
      'start-placeholder': `${$t('common.component.dataRangePicker.placeholder.monthrangeStart')}`,
      'end-placeholder': `${$t('common.component.dataRangePicker.placeholder.monthrangeEnd')}`
    },
    datetime: {
      format: 'yyyy-MM-dd HH:mm:ss',
      'value-format': 'yyyy-MM-dd HH:mm:ss',
      placeholder: `${$t('common.component.dataRangePicker.placeholder.datetime')}`
    },
    datetimerange: {
      format: 'yyyy-MM-dd HH:mm:ss',
      'value-format': 'yyyy-MM-dd HH:mm:ss',
      'range-separator': '~',
      'start-placeholder': `${$t('common.component.dataRangePicker.placeholder.datetimerangeStart')}`,
      'end-placeholder': `${$t('common.component.dataRangePicker.placeholder.datetimerangeEnd')}`
    }
  };
  const typeAttrs = baseAttrs[props.type] || {};
  return {
    ...typeAttrs,
    ...attrs
  };
});

const state = reactive({
  dateOptions: props.shortcuts
});

const getToday = () => {
  const date = new Date();
  return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
};
const subtractDays = (date: Date, days: number) => {
  const newDate = new Date(date);
  newDate.setDate(newDate.getDate() - days);
  return newDate.getTime();
};
const subtractMonths = (date: Date, months: number) => {
  const newDate = new Date(date);
  newDate.setMonth(newDate.getMonth() - months);
  return newDate.getTime();
};

// 获取快捷配置
const getShortcuts = (type: string) => {
  if (type === 'datetimerange') {
    const rangeShortcuts: Shortcuts = {
      [$t('common.today')]: () => [getToday(), new Date().getTime()],
      [$t('common.week')]: () => [subtractDays(new Date(), 7), new Date().getTime()],
      [$t('common.months')]: () => [subtractMonths(new Date(), 30), new Date().getTime()],
      [$t('common.threeMonths')]: () => [subtractMonths(new Date(), 3), new Date().getTime()],
      [$t('common.sixMonths')]: () => [subtractMonths(new Date(), 6), new Date().getTime()],
      [$t('common.oneYear')]: () => [subtractMonths(new Date(), 12), new Date().getTime()]
    };
    return rangeShortcuts;
  } else if (type === 'date') {
    const rangeShortcuts: Shortcuts = {
      [$t('common.today')]: () => [getToday(), new Date().getTime()],
      [$t('common.yesterday')]: () => [subtractDays(new Date(), 1), new Date().getTime()],
      [$t('common.week')]: () => [subtractDays(new Date(), 7), new Date().getTime()]
    };
    return rangeShortcuts;
  } else if (type === 'daterange') {
    const rangeShortcuts: Shortcuts = {
      [$t('common.week')]: () => [subtractDays(new Date(), 7), new Date().getTime()],
      [$t('common.months')]: () => [subtractMonths(new Date(), 1), new Date().getTime()],
      [$t('common.threeMonths')]: () => [subtractMonths(new Date(), 3), new Date().getTime()]
    };
    return rangeShortcuts;
  } else if (type === 'monthrange') {
    const rangeShortcuts: Shortcuts = {
      [$t('common.months')]: () => [subtractMonths(new Date(), 1), new Date().getTime()],
      [$t('common.sixMonths')]: () => [subtractMonths(new Date(), 6), new Date().getTime()],
      [$t('common.oneYear')]: () => [subtractMonths(new Date(), 12), new Date().getTime()]
    };
    return rangeShortcuts;
  } else if (type === 'datetime') {
    const rangeShortcuts: Shortcuts = {
      [$t('common.today')]: () => [getToday(), new Date().getTime()],
      [$t('common.yesterday')]: () => [subtractDays(new Date(), 1), new Date().getTime()],
      [$t('common.week')]: () => [subtractDays(new Date(), 7), new Date().getTime()]
    };
    return rangeShortcuts;
  }
  return {};
};

const dateChange = (val: any[]) => {
  if (props.type === 'daterange' && val) {
    let startTime = val[0];
    let endTime = val[1];
    if (props.plusTime) {
      startTime += ' 00:00:00';
      endTime += ' 23:59:59';
    }
    time.value = [startTime, endTime];
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-expect-error
    emit('change', [startTime, endTime]);
    DatePicker.value.getElementsByClassName('n-input__input-el')[0].blur();
    DatePicker.value.getElementsByClassName('n-input__input-el')[1].blur();
  } else {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-expect-error
    emit('change', val);
    if (props.type.includes('range')) {
      DatePicker.value.getElementsByClassName('n-input__input-el')[0].blur();
      DatePicker.value.getElementsByClassName('n-input__input-el')[1].blur();
    } else {
      DatePicker.value.getElementsByClassName('n-input__input-el')[0].blur();
    }
  }
};
if (props.isPickerOptions) {
  state.dateOptions = getShortcuts(props.type);
}
watch(
  () => props.shortcuts,
  val => {
    if (props.isPickerOptions) {
      const shortcuts = getShortcuts(props.type);
      state.dateOptions = shortcuts;
    } else {
      state.dateOptions = val;
    }
  },
  { deep: true }
);
// 暴露方法出去
defineExpose({ state });
</script>

<template>
  <div ref="DatePicker" class="t-date-picker">
    <NDatePicker
      v-model="time"
      :type="type"
      :update-value-on-close="true"
      :shortcuts="state.dateOptions"
      clearable
      v-bind="attrsBind"
      @update:value="dateChange"
    />
  </div>
</template>

<style scoped>
.t-date-picker {
  width: 100%;
}
</style>
